// Copyright (C) 2010  Joan Puigcerver Perez, <joapuipe@gmail.com>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.
//

#include <SAXMoviesHandler.hpp>

#include <iostream>

SAXMoviesHandler::SAXMoviesHandler( Database * database, 
				    std::ostream& logf, 
				    ost::Mutex& logm ) 
  : db(database), curr_movie(0), proc_aka(false), proc_genre(false),
    logfile(logf), log_mutex(logm)
{
}

void SAXMoviesHandler::startDocument ( )
{
  _ktitle = XMLString::transcode("title");
  _kyear = XMLString::transcode("year");
  _kmedia = XMLString::transcode("media");
  _ksusp = XMLString::transcode("suspended"); 
}

void SAXMoviesHandler::endDocument ( )
{
  XMLString::release(&_ktitle);
  XMLString::release(&_kyear);
  XMLString::release(&_kmedia);
  XMLString::release(&_ksusp);
}

void SAXMoviesHandler::startElement ( const XMLCh* const uri,
				      const XMLCh* const localname,
				      const XMLCh* const qname,
				      const Attributes&  attrs )
{
  char * elem = XMLString::transcode(localname);

  if ( XMLString::equals(elem, "movie") ) {
    const XMLCh * title = attrs.getValue( _ktitle );
    const XMLCh * year  = attrs.getValue( _kyear );
    const XMLCh * media = attrs.getValue( _kmedia );
    const XMLCh * suspended = attrs.getValue( _ksusp ); 
   
    curr_movie = createMovie(title, year, media, suspended);
  } else if ( XMLString::equals(elem, "aka") ) {
    proc_aka = true;
  } else if ( XMLString::equals(elem, "genre") ) {
    proc_genre = true;
  }

  buffer.clear();

  XMLString::release(&elem);
}

void SAXMoviesHandler::endElement( const XMLCh* const uri, 
				   const XMLCh* const localname,
				   const XMLCh* const qname )
{
  char * elem = XMLString::transcode(localname);

  if ( XMLString::equals(elem, "movie") ) {
    curr_movie = 0;
  } else if ( XMLString::equals(elem, "aka") ) {
    addAka(buffer);
    proc_aka = false;
  } else if ( XMLString::equals(elem, "genre") ) {
    addGenre(buffer);
    proc_genre = false;
  }

  XMLString::release(&elem);
}

void SAXMoviesHandler::characters( const XMLCh* const chars,
				   const XMLSize_t length )
{
  if ( proc_aka || proc_genre )
    buffer.append(chars);
}

void SAXMoviesHandler::fatalError( const SAXParseException& exception )
{
  throw exception;
}

void SAXMoviesHandler::error( const SAXParseException &exception )
{
  throw exception;
}

Movie* SAXMoviesHandler::createMovie(const XMLCh * title, 
				     const XMLCh * year, 
				     const XMLCh * media, 
				     const XMLCh * suspended )
{
  Movie * mov;
  char * title_ch = XMLString::transcode( title );
  
  if ( !(mov = db->movies.add_movie(title_ch, xml_get_year(year), xml_get_media(media), 
				    xml_get_suspended(suspended))) ) {
    print_log_line("DUPLICATED MOVIE TITLE! IGNORING INSERTION OF: " + std::string(title_ch), 
		   logfile, log_mutex);
  }
  
  XMLString::release(&title_ch);
  return mov;
}

void SAXMoviesHandler::addAka(const XercesString& aka)
{
  if( curr_movie == 0 ) {
    print_log_line("YOU SHOULD NOT BE HERE! - addAka()", logfile, log_mutex);
  } else {
    char * title_aka = XMLString::transcode( aka.c_str() );
    db->movies.add_aka(title_aka, curr_movie);
    XMLString::release(&title_aka);
  }
}

void SAXMoviesHandler::addGenre(const XercesString& genre)
{
  if ( curr_movie == 0 ) {
    print_log_line("YOU SHOULD NOT BE HERE! - addGenre()", logfile, log_mutex);
  } else {
    curr_movie->add_genre( xml_get_genre(genre.c_str()) );
  }
}

